
template<typename T>
WorkChannelImpl<T>::WorkChannelImpl() {
	message_loop_ = NULL;
	InterlockedExchange(&created_, 0);
}

template<typename T>
WorkChannelImpl<T>::~WorkChannelImpl() {
}

template<typename T>
void WorkChannelImpl<T>::Create(MessageLoop* message_loop) {
	message_loop_ = message_loop;
	InternalCreate();
}

template<typename T>
void WorkChannelImpl<T>::Destroy() {
  if (created_) {
    channel_->Close();
    channel_.reset();
    InterlockedExchange(&created_, 0);
  }
}

// IPC::Listener
template<typename T>
bool WorkChannelImpl<T>::OnMessageReceived(const IPC::Message& message) {
	return false;
}

template<typename T>
void WorkChannelImpl<T>::OnChannelConnected(int32 peer_pid) {

}

template<typename T>
void WorkChannelImpl<T>::OnChannelError() {
	Destroy();
}

template<typename T>
bool WorkChannelImpl<T>::Send(IPC::Message* message) {
  return channel_->Send(message);
}

template<typename T>
std::wstring WorkChannelImpl<T>::GetLaunchFile() const {
	assert(false);
	return L"";
}

template<typename T>
void WorkChannelImpl<T>::InternalCreate() {
	DCHECK(!created_);
	if (CreateChannel()) {
		LaunchPeer();
		InterlockedExchange(&created_, 1);
	}
}

template<typename T>
void WorkChannelImpl<T>::InternalCheckCreate() {
	if (!created_) InternalCreate();
}

template<typename T>
bool WorkChannelImpl<T>::CreateChannel() {
	channel_id_ = IPC::Channel::GenerateVerifiedChannelID("");
	channel_.reset(new IPC::Channel(channel_id_, IPC::Channel::MODE_SERVER,	this));
	return channel_->Connect();
}

template<typename T>
bool WorkChannelImpl<T>::LaunchPeer() {
	base::ProcessHandle handle = base::kNullProcessHandle;
	base::LaunchOptions options;
	base::LaunchProcess(MakeCmdLine(), options, &handle);
	return true;
}

template<typename T>
CommandLine WorkChannelImpl<T>::MakeCmdLine() {
	std::wstring path;
	FilePath module_path;
	if (PathService::Get(base::FILE_MODULE, &module_path)) {
		T* pthis = static_cast<T*>(this);
		path = L"\"";
		path += module_path.DirName().Append(pthis->GetLaunchFile()).value();
		path += L"\"";
	}
	CommandLine cl(CommandLine::FromString(path));
	cl.AppendSwitchASCII(kChannelName, channel_id_);
	return cl;
}
